package ru.agiledev.akb.client.window;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.*;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;
import ru.agiledev.akb.client.*;
import ru.agiledev.akb.shared.User;

/**
 * Created by a.kirillov
 * Date: 5/16/11 Time: 1:41 PM
 */
public class EditProfileWindow extends DialogBox {

    private TextBox loginField;
    private TextBox firstNameField;
    private TextBox lastNameField;
    private TextBox affilationField;
    private TextBox emailField;
    private HorizontalPanel loginError;
    private HorizontalPanel firstNameError;
    private HorizontalPanel lastNameError;
    private HorizontalPanel emailError;



    private final ValidationServiceAsync validationService = GWT.create(ValidationService.class);
    private final RegistrationServiceAsync registrationService = GWT.create(RegistrationService.class);
    private User user;

    public EditProfileWindow(int x, int y) {
        setModal(true);
        setAnimationEnabled(true);
        setText("Редактирование профиля");
        addStyleName("editProfileDialogBox");
        setPopupPosition(x, y);

        VerticalPanel registrationPanel = new VerticalPanel();
        registrationPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT);

        user = AspectKnowledgeBaseApplication.get().getUser();
        HorizontalPanel words = new HorizontalPanel();
        HTML hello = new HTML("<center>Редактирование профиля пользователя<br> "+user.getFirstName()+" "+user.getLastName()+"<center>");
        words.add(hello);

        HorizontalPanel enterYourData = new HorizontalPanel();
        enterYourData.setSpacing(4);
        enterYourData.setHorizontalAlignment(HorizontalPanel.ALIGN_RIGHT);
        HTML inputPrompt = new HTML("<b>Заполните форму</b>");
        enterYourData.add(inputPrompt);

        HorizontalPanel loginPanel = new HorizontalPanel();
        loginPanel.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE);
        loginPanel.setSpacing(4);

        Label login = new Label("Логин");
        loginField = new TextBox();
        loginField.setValue(user.getLogin());
        loginField.getElement().setId("login");

        loginPanel.add(login);
        loginPanel.add(loginField);

        loginError = new HorizontalPanel();
        loginError.setSpacing(2);

        HorizontalPanel firstNamePanel = new HorizontalPanel();
        firstNamePanel.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE);
        firstNamePanel.setSpacing(4);
        Label firstName = new Label("Имя");
        firstNameField = new TextBox();
        firstNameField.setValue(user.getFirstName());
        firstNameField.getElement().setId("firstName");

        firstNamePanel.add(firstName);
        firstNamePanel.add(firstNameField);

        firstNameError = new HorizontalPanel();
        firstNameError.setSpacing(2);

        HorizontalPanel lastNamePanel = new HorizontalPanel();
        lastNamePanel.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE);
        lastNamePanel.setSpacing(4);
        Label lastName = new Label("Фамилия");
        lastNameField = new TextBox();
        lastNameField.setValue(user.getLastName());
        lastNameField.getElement().setId("lastName");

        lastNamePanel.add(lastName);
        lastNamePanel.add(lastNameField);

        lastNameError = new HorizontalPanel();
        lastNameError.setSpacing(2);

        HorizontalPanel affilationPanel = new HorizontalPanel();
        affilationPanel.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE);
        affilationPanel.setSpacing(4);
        Label affilation = new Label("Организация");
        affilationField = new TextBox();
        affilationField.setValue(user.getAffilation());

        affilationPanel.add(affilation);
        affilationPanel.add(affilationField);

        HorizontalPanel emailPanel = new HorizontalPanel();
        emailPanel.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE);
        emailPanel.setSpacing(4);
        Label email = new Label("E-mail");
        emailField = new TextBox();
        emailField.setValue(user.getEmail());
        emailField.getElement().setId("email");

        emailPanel.add(email);
        emailPanel.add(emailField);

        emailError = new HorizontalPanel();
        emailError.setSpacing(2);


        HorizontalPanel buttons = new HorizontalPanel();
        buttons.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE);
        buttons.setSpacing(4);
        Button confirm = new Button("Сохранить");

        confirm.addClickHandler(new RegistrationHandler());

        Button cancel = new Button("Отменить");
        cancel.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent clickEvent) {
                hide();
            }
        });

        buttons.add(confirm);
        buttons.add(cancel);

        registrationPanel.add(hello);
        registrationPanel.add(enterYourData);
        registrationPanel.add(loginPanel);
        registrationPanel.add(loginError);
        registrationPanel.add(firstNamePanel);
        registrationPanel.add(firstNameError);
        registrationPanel.add(lastNamePanel);
        registrationPanel.add(lastNameError);
        registrationPanel.add(affilationPanel);
        registrationPanel.add(emailPanel);
        registrationPanel.add(emailError);
        registrationPanel.add(buttons);

        add(registrationPanel);


        //======================== Field focus listeners =====================
        loginField.addFocusHandler(new FieldFocusHandler());
        loginField.addBlurHandler(new FieldBlurHandler());
        firstNameField.addFocusHandler(new FieldFocusHandler());
        firstNameField.addBlurHandler(new FieldBlurHandler());
        lastNameField.addFocusHandler(new FieldFocusHandler());
        lastNameField.addBlurHandler(new FieldBlurHandler());
        affilationField.addFocusHandler(new FieldFocusHandler());
        emailField.addFocusHandler(new FieldFocusHandler());
        emailField.addBlurHandler(new FieldBlurHandler());
    }


    class FieldBlurHandler implements BlurHandler {
        @Override
        public void onBlur(BlurEvent event) {
            Element e = ((TextBox)event.getSource()).getElement();

            //Login validation
            if("login".equals(e.getId())&&!user.getLogin().equals(loginField.getText())){

                AsyncCallback<Boolean> validation = new AsyncCallback<Boolean>() {
                    @Override
                    public void onFailure(Throwable caught) {
                        HTML error = new HTML(caught.getMessage());
                        error.setStyleName("loginErrorPanel");
                        loginError.add(error);
                        Element e = loginField.getElement();
                        DOM.setStyleAttribute(e, "background", "orange");
                    }

                    @Override
                    public void onSuccess(Boolean result) {
                        if(!result){
                            HTML error = new HTML("Допустимы латинские буквы и цифры.<br>Длина логина не менее 5 символов.");
                            error.setStyleName("loginErrorPanel");
                            loginError.add(error);
                            Element e = loginField.getElement();
                            DOM.setStyleAttribute(e, "background", "orange");
                        }
                    }
                };

                validationService.validateLogin(loginField.getText(), validation);
            }

            if("firstName".equals(e.getId())&&!user.getFirstName().equals(firstNameField.getText())){
                if(firstNameField.getText().length()<2){
                    HTML error = new HTML("Имя должно состоять из двух и более букв");
                    error.setStyleName("loginErrorPanel");
                    firstNameError.add(error);

                    DOM.setStyleAttribute(e, "background", "orange");
                }
            }

            if("lastName".equals(e.getId())&&!user.getLastName().equals(lastNameField.getText())){
                if(lastNameField.getText().length()<2){
                    HTML error = new HTML("Фамилия должна состоять из двух и более букв");
                    error.setStyleName("loginErrorPanel");
                    lastNameError.add(error);

                    DOM.setStyleAttribute(e, "background", "orange");
                }
            }

            if("email".equals(e.getId())&&!user.getEmail().equals(emailField.getText())){

                AsyncCallback<Boolean> validation = new AsyncCallback<Boolean>() {
                    @Override
                    public void onFailure(Throwable caught) {
                        HTML error = new HTML(caught.getMessage());
                        error.setStyleName("loginErrorPanel");
                        emailError.add(error);
                        Element e = emailField.getElement();
                        DOM.setStyleAttribute(e, "background", "orange");
                    }

                    @Override
                    public void onSuccess(Boolean result) {
                        if(!result){
                            HTML error = new HTML("Некорректный e-mail");
                            error.setStyleName("loginErrorPanel");
                            emailError.add(error);
                            Element e = emailField.getElement();
                            DOM.setStyleAttribute(e, "background", "orange");
                        }
                    }
                };

                validationService.validateEmail(emailField.getText(), validation);
            }
        }
    }

    class FieldFocusHandler implements FocusHandler {
        @Override
        public void onFocus(FocusEvent focusEvent) {

            Element e = ((TextBox)focusEvent.getSource()).getElement();
            if("login".equals(e.getId())){
                DOM.setStyleAttribute(e, "background", "white");

                if((loginError.getWidgetCount()>0)&&(loginError.getWidget(0)!=null)){
                    loginError.remove(0);
                }
            }

            if("firstName".equals(e.getId())){
                DOM.setStyleAttribute(e, "background", "white");

                if((firstNameError.getWidgetCount()>0)&&(firstNameError.getWidget(0)!=null)){
                    firstNameError.remove(0);
                }
            }

            if("lastName".equals(e.getId())){
                DOM.setStyleAttribute(e, "background", "white");

                if((lastNameError.getWidgetCount()>0)&&(lastNameError.getWidget(0)!=null)){
                    lastNameError.remove(0);
                }
            }

            if("email".equals(e.getId())){
                DOM.setStyleAttribute(e, "background", "white");

                if((emailError.getWidgetCount()>0)&&(emailError.getWidget(0)!=null)){
                    emailError.remove(0);
                }
            }


        }
    }

    class RegistrationHandler implements ClickHandler {
        @Override
        public void onClick(ClickEvent clickEvent) {
            String login = loginField.getText();
            String firstName = firstNameField.getText();
            String lastName = lastNameField.getText();
            String affilation = affilationField.getText();
            String email = emailField.getText();

            boolean error = false;

            if(login.length()==0){
                Element e = loginField.getElement();
                DOM.setStyleAttribute(e, "background", "orange");
                error = true;
            }

            //First name validation
            if(firstName.length()==0){
                Element e = firstNameField.getElement();
                DOM.setStyleAttribute(e, "background", "orange");
                error = true;
            }

            //Last name validation
            if(lastName.length()==0){

                Element e = lastNameField.getElement();
                DOM.setStyleAttribute(e, "background", "orange");
                error = true;
            }

            //Last name validation
            if(email.length()==0){

                Element e = emailField.getElement();
                DOM.setStyleAttribute(e, "background", "orange");
                error = true;
            }

            if( (loginError.getWidgetCount()>0)&&(loginError.getWidget(0)!=null) ||
                    (firstNameError.getWidgetCount()>0)&&(firstNameError.getWidget(0)!=null) ||
                    (lastNameError.getWidgetCount()>0)&&(lastNameError.getWidget(0)!=null) ||
                    (emailError.getWidgetCount()>0)&&(emailError.getWidget(0)!=null) ||
                    (emailError.getWidgetCount()>0)&&(emailError.getWidget(0)!=null)){

                error = true;
            }


            if(!error){
                User newUser = new User(null, login, firstName, lastName, affilation, email, "");
                newUser.setId(user.getId());

                AsyncCallback<User> registration = new AsyncCallback<User>() {
                    @Override
                    public void onFailure(Throwable caught) {
                        //TODO: serverError
                        int i=0;
                        if((loginError.getWidgetCount()>0)&&(loginError.getWidget(0)!=null)){
                            loginError.remove(0);
                        }

                        HTML error = new HTML(caught.getMessage());
                        error.setStyleName("loginErrorPanel");
                        loginError.add(error);

                    }

                    @Override
                    public void onSuccess(User user) {
                        if(user!=null){
                            hide();
                            AspectKnowledgeBaseApplication.get().setUser(user);

                            final DialogBox dialogBox = new DialogBox();
                            dialogBox.setPopupPosition(RootPanel.get().getOffsetWidth()/2-160, RootPanel.get().getOffsetHeight()/2-150);
                            dialogBox.setText("Данные сохранены");
                            dialogBox.setWidth("310px");
                            dialogBox.setHeight("100px");
                            dialogBox.setModal(true);

                            VerticalPanel dialogPanel = new VerticalPanel();
                            dialogPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);


                            dialogPanel.add(new HTML("<center>Данные были успешно сохранены.</center>"));
                            HorizontalPanel dialogBoxButtons = new HorizontalPanel();
                            dialogBoxButtons.setSpacing(4);
                            dialogBoxButtons.setHorizontalAlignment(HorizontalPanel.ALIGN_CENTER);
                            Button ok = new Button("Ок");
                            ok.addClickHandler(new ClickHandler() {
                                @Override
                                public void onClick(ClickEvent clickEvent) {
                                    dialogBox.hide();
                                }
                            });
                            dialogBoxButtons.add(ok);
                            dialogPanel.add(dialogBoxButtons);
                            dialogBox.add(dialogPanel);
                            dialogBox.show();

                        }
                    }
                };
                try {
                    registrationService.updateUser(newUser, registration);
                } catch (Exception e) {
                    Window.alert("Внутренняя ошибка сервера. Обратитесь к администратору");
                    e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                }
            }

        }
    }
}
